#pragma once
#include <Windows.h>
#include <hash_map>
#include "Const.h"
#include "Define.h"
#include "ObjKeyGenerator.h"



class User;
class ServerSession;



typedef stdext::hash_map<DWORD, User*>		USER_MAP;
typedef USER_MAP::iterator					USER_MAP_ITER;
typedef std::pair<DWORD, User*>				USER_MAP_PAIR;

class Channel
{
public:
	Channel(void);
	~Channel(void);

	VOID					Init();
	VOID					Release();
	VOID					Update();
	VOID                    Send(BYTE* pMsg,WORD wSize);
	VOID					RemoveVillage( DWORD dwZoneKey );
//	VOID					RemoveBattleZone( DWORD dwZoneKey );
	VOID					RemoveLobby( DWORD dwZoneKey );
	VOID					RemoveMissionZone( DWORD dwZoneKey );
	VOID					RemoveHuntingZone( DWORD dwZoneKey );
	VOID					RemoveQuestZone( DWORD dwZoneKey );
	VOID					RemovePVPZone( DWORD dwZoneKey );
	VOID					RemoveEventZone( DWORD dwZoneKey );
	VOID					RemoveGuildZone( DWORD dwZoneKey );
	VOID					RemoveSiegeZone( DWORD dwZoneKey );
	VOID					RemoveFriendChat( DWORD dwZoneKey );

	VOID					AddUser( User *pUser);
	VOID					RemoveUser( User *pUser );
	VOID					UserEnterCharScene( User *pUser );
	VOID					UserEnterVillage( User *pUser, DWORD dwNewZoneKey );
//	VOID					UserEnterBattleZone( User *pUser, DWORD dwNewZoneKey );
	VOID					UserEnterLobby( User *pUser, DWORD dwNewZoneKey );
	VOID					UserEnterMissionZone( User *pUser, DWORD dwNewZoneKey );
	VOID					UserEnterHuntingZone( User *pUser, DWORD dwNewZoneKey );
	VOID					UserEnterQuestZone( User *pUser, DWORD dwNewZoneKey );
	VOID					UserEnterPVPZone( User *pUser, DWORD dwNewZoneKey );
	VOID					UserEnterEventZone( User *pUser, DWORD dwNewZoneKey );
	VOID					UserEnterGuildZone( User *pUser, DWORD dwNewZoneKey );
	VOID					UserEnterSiegeZone( User *pUser, DWORD dwNewZoneKey );
	VOID					UserEnterFriendChat( User *pUser, DWORD dwNewZoneKey );

	VOID					SendToAll( BYTE *pMsg, WORD wSize );
	BOOL					SendToOneVillage( DWORD dwFieldCode, BYTE *pMsg, WORD wSize );
	VOID					SendToVillages( BYTE *pMsg, WORD wSize );
//	VOID					SendToBattleZones( BYTE *pMsg, WORD wSize );
	VOID					SendToLobby( BYTE *pMsg, WORD wSize );
	VOID					SendToMissionZones( BYTE *pMsg, WORD wSize );
	VOID					SendToHuntingZones( BYTE *pMsg, WORD wSize );
	VOID					SendToQuestZones( BYTE *pMsg, WORD wSize );
	VOID					SendToPVPZones( BYTE *pMsg, WORD wSize );
	VOID					SendToEventZones( BYTE *pMsg, WORD wSize );
	VOID					SendToGuildZones( BYTE *pMsg, WORD wSize );
	VOID					SendToSiegeZones( BYTE *pMsg, WORD wSize );
	

	inline VOID				SetChannelID( DWORD dwChannelID ) { m_dwChannelID = dwChannelID; }
	inline DWORD			GetChannelID() { return m_dwChannelID; }
	VOID                    SetChannelSession(ServerSession* pServerSession){m_pServerSession = pServerSession;}
	VOID					DisplayInfo(){}

	VOID					UserLeavePrevZone( User *pUser );

	inline VOID						SetVillageUserNum( DWORD &dwUserNum ) { m_dwVillageUserNum = dwUserNum; }
	inline VOID						SetLobbyUserNum( DWORD &dwUserNum ) { m_dwLobbyUserNum = dwUserNum; }
	inline VOID						SetMissionUserNum( DWORD &dwUserNum ) { m_dwMissionUserNum = dwUserNum; }
	inline VOID						SetHuntingUserNum( DWORD &dwUserNum ) { m_dwHuntingUserNum = dwUserNum; }
	inline VOID						SetQuestUserNum( DWORD &dwUserNum ) { m_dwQuestUserNum = dwUserNum; }
	inline VOID						SetPVPUserNum( DWORD &dwUserNum ) { m_dwPVPUserNum = dwUserNum; }
	inline VOID						SetEventUserNum( DWORD &dwUserNum ) { m_dwEventUserNum = dwUserNum; }
	inline VOID						SetGuildUserNum( DWORD &dwUserNum ) { m_dwGuildUserNum = dwUserNum; }
	inline VOID						SetSiegeUserNum( DWORD &dwUserNum ) { m_dwSiegeUserNum = dwUserNum; }

	inline VOID						IncVillageUserNum() { m_dwVillageUserNum++; }
	inline VOID						IncLobbyUserNum() { m_dwLobbyUserNum++; }
	inline VOID						IncMissionUserNum() { m_dwMissionUserNum++; }
	inline VOID						IncHuntingUserNum() { m_dwHuntingUserNum++; }
	inline VOID						IncQuestUserNum() { m_dwQuestUserNum++; }
	inline VOID						IncPVPUserNum() { m_dwPVPUserNum++; }
	inline VOID						IncEventUserNum() { m_dwEventUserNum++; }
	inline VOID						IncGuildUserNum() { m_dwGuildUserNum++; }
	inline VOID						IncSiegeUserNum() { m_dwSiegeUserNum++; }

	inline VOID						DecVillageUserNum() { if( m_dwVillageUserNum > 0 ) m_dwVillageUserNum--; }
	inline VOID						DecLobbyUserNum() { if( m_dwLobbyUserNum > 0 ) m_dwLobbyUserNum--; }
	inline VOID						DecMissionUserNum() { if( m_dwMissionUserNum > 0 ) m_dwMissionUserNum--; }
	inline VOID						DecHuntingUserNum() { if( m_dwHuntingUserNum > 0 ) m_dwHuntingUserNum--; }
	inline VOID						DecQuestUserNum() { if( m_dwQuestUserNum > 0 ) m_dwQuestUserNum--; }
	inline VOID						DecPVPUserNum() { if( m_dwPVPUserNum > 0 ) m_dwPVPUserNum--; }
	inline VOID						DecEventUserNum() { if( m_dwEventUserNum > 0 ) m_dwEventUserNum--; }
	inline VOID						DecGuildUserNum() { if( m_dwGuildUserNum > 0 ) m_dwGuildUserNum--; }
	inline VOID						DecSiegeUserNum() { if( m_dwSiegeUserNum > 0 ) m_dwSiegeUserNum--; }

	inline DWORD					GetTotalUserNum() { return (DWORD)m_mapUsers.size(); }
	inline DWORD					GetVillageUserNum() { return (DWORD)m_dwVillageUserNum; }
	inline DWORD					GetLobbyUserNum() { return (DWORD)m_dwLobbyUserNum; }
	inline DWORD					GetMissionUserNum() { return (DWORD)m_dwMissionUserNum; }
	inline DWORD					GetHuntingUserNum() { return (DWORD)m_dwHuntingUserNum; }
	inline DWORD					GetQuestUserNum() { return (DWORD)m_dwQuestUserNum; }
	inline DWORD					GetPVPUserNum() { return (DWORD)m_dwPVPUserNum; }
	inline DWORD					GetEventUserNum() { return (DWORD)m_dwEventUserNum; }
	inline DWORD					GetGuildUserNum() { return (DWORD)m_dwGuildUserNum; }
	inline DWORD					GetSiegeUserNum() { return (DWORD)m_dwSiegeUserNum; }


	inline KEYTYPE					AllocKey()						{ return m_ChatRoomKeyGenerator.GetKey(); }
	inline VOID						FreeKey( KEYTYPE Key )			{ m_ChatRoomKeyGenerator.RestoreKey(Key); }

private:
 
	ServerSession*          m_pServerSession;
	CObjKeyGenerator	    m_ChatRoomKeyGenerator; 
	USER_MAP				m_mapUsers;
	DWORD					m_dwChannelID;
	DWORD					m_dwVillageUserNum;
	DWORD					m_dwLobbyUserNum;
	DWORD					m_dwMissionUserNum;
	DWORD					m_dwHuntingUserNum;
	DWORD					m_dwQuestUserNum;
	DWORD					m_dwPVPUserNum;
	DWORD					m_dwEventUserNum;
	DWORD					m_dwGuildUserNum;
	DWORD					m_dwSiegeUserNum;
};
